﻿using CacheManager.Core;
using DH.Core;
using DH.Core.Exceptions;
using DH.Core.Helper;
using DH.Data;
using DH.Data.Extensions;
using DH.Data.ORM.EF;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DH.Service
{
   public abstract class BaseService<T,TKey>:IBaseService where T:BaseEntity<TKey>
    {

        protected EFCoreUnitOfWork<DbContext> _unitOfWork;
        protected EFCoreBaseRepository<T, TKey> _repository;
        protected ICacheManager<object> _cacheManager;
        public BaseService(IServiceCollection service,DbCoreUnitOfWork unitOfWork)
        {
            _unitOfWork =unitOfWork;
            //_repository= service.BuildServiceProvider().GetService<IEFCoreQueryableRepository<T, TKey>>() as EFCoreBaseRepository<T,TKey>;
            _repository = new EFCoreBaseRepository<T, TKey>(unitOfWork.Context);

            _cacheManager = CacheHelper.CustomManager;
            
        }

        #region 异步操作

        protected OrderBy<T> Ordering => new OrderBy<T>(query => query.OrderBy(a => a.SortIndex));

        public async Task<IEnumerable<T>> GetAllAsync()
        {
            //return await Task.FromResult(_repository.QueryFilter(orderBy: Ordering.Expression));
            return await Task.FromResult(_repository.Query());
        }
        /// <summary>
        /// 根据ID获取实体数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<T> GetAsync(TKey id)
        {
            return await _repository.GetByIdAsync(id);

        }
        public async Task<IEnumerable<T>> GetByQueryAsync(Expression<Func<T, bool>> predicate)
        {
            return await _repository.QueryFilter(predicate, orderBy: Ordering.Expression).ToListAsync();
        }

        public async Task<T> InsertAsync(T entity)
        {
            if (entity == null) throw new ArgumentException("No codetable provided", nameof(entity));

            await _unitOfWork.ExecuteAndCommitAsync(() =>
            {
                return _repository.AddAsync(entity);
            });
            return entity;
        }

        public async Task<T> UpdateAsync(T entity)
        {
            if (entity == null) throw new EntityNotFoundException(nameof(entity), 0);

            await _unitOfWork.ExecuteAndCommitAsync(() =>
            {
                return _repository.UpdateAsync(entity);
            });
            return entity;
        }

        public async Task DeleteAsync(TKey id)
        {
            var entity = _repository.GetById(id);
            if (entity == null) throw new EntityNotFoundException(typeof(T).Name, id);
            await _unitOfWork.ExecuteAndCommitAsync(() =>
            {
                return _repository.DeleteAsync(entity);
            });
        }

        public async Task DeleteAsync(IEnumerable<T> entitys)
        {
            if (entitys == null) throw new EntityNotFoundException(typeof(T).Name, entitys);

            await  _unitOfWork.ExecuteAndCommitAsync(() => {
               return _repository.DeleteAsync(entitys);
            });
        }
        #endregion

        #region 同步操作
        /// <summary>
        /// 根据ID获取实体数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetSync(TKey id)
        {
            return _repository.GetById(id);
        }
        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        public IEnumerable<T> GetOrderAllSync()
        {
            return _repository.QueryFilter(orderBy: Ordering.Expression);
        }
        public IEnumerable<T> GetAllSync() {
            return _repository.Query();
        }

        public IEnumerable<T> GetByQuery(Expression<Func<T, bool>> predicate)
        {
            return _repository.QueryFilter(predicate, orderBy: Ordering.Expression);
        }
        public IEnumerable<T> GetByQuery(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy) {
            return _repository.QueryFilter(predicate, orderBy);
        }

        public T InsertSync(T entity)
        {
            if (entity == null) throw new ArgumentException("实体类不能为空", nameof(entity));
              
            _unitOfWork.ExecuteAndCommit(()=> {
                _repository.Add(entity);
            });
            return entity;

        }
        public T UpdateSync(T entity)
        {
            if (entity == null) throw new ArgumentException("实体类不能为空", nameof(entity));
            
            _unitOfWork.ExecuteAndCommit(() => {
                _repository.Update(entity);
            });
            return entity;
        }
        public T DeleteSync(TKey id)
        {
            var entity = _repository.GetById(id);
            if (entity == null) throw new EntityNotFoundException(typeof(T).Name, id);
            
            _unitOfWork.ExecuteAndCommit(() => {
                _repository.Delete(entity);
            });
            return entity;
        }
        public void DeleteSync(IEnumerable<T> entitys) {
            if (entitys == null) throw new EntityNotFoundException(typeof(T).Name, entitys);

            _unitOfWork.ExecuteAndCommit(() => {
                _repository.Delete(entitys);
            });
        }
        #endregion

        public virtual void Dispose()
        {

        }
    }
}
